package co.edu.usbcali.sap.modelo.control;


import co.edu.usbcali.sap.dataaccess.daoFactory.XMLHibernateDaoFactory;
import co.edu.usbcali.sap.dataaccess.sessionFactory.HibernateSessionFactory;
import co.edu.usbcali.sap.exceptions.*;
import co.edu.usbcali.sap.modelo.*;
import co.edu.usbcali.sap.presentation.businessDelegate.BusinessDelegatorView;
import co.edu.usbcali.sap.utilities.Utilities;

import java.io.File;
import java.io.FileInputStream;
import java.math.BigDecimal;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;

import com.icesoft.faces.component.inputfile.InputFile;


/**
 * interface DocumentosProyectoLogic
 * @author Zathura Code Generator http://code.google.com/p/zathura
 *
 */
public class DocumentosProyectoLogic implements IDocumentosProyectoLogic {
    public List<DocumentosProyecto> getDocumentosProyecto()
        throws Exception {
        List<DocumentosProyecto> list = new ArrayList<DocumentosProyecto>();

        try {
            list = XMLHibernateDaoFactory.getInstance()
                                         .getDocumentosProyectoDAO().findAll();
        } catch (Exception e) {
            throw new ZMessManager().new GettingException(ZMessManager.ALL +
                "DocumentosProyecto");
        } finally {
        }

        return list;
    }

    public void saveDocumentosProyecto(Long docproArchivo,
        Integer docproCodigo, String docproFormato, Integer proCodigo_Proyecto,
        Integer tipdocCodigo_TipoDocumento) throws Exception {
        DocumentosProyecto entity = null;

        try {
            if (docproArchivo == null) {
                throw new ZMessManager().new EmptyFieldException(
                    "docproArchivo");
            }

            if (docproCodigo == null) {
                throw new ZMessManager().new EmptyFieldException("docproCodigo");
            }

            if (docproFormato == null) {
                throw new ZMessManager().new EmptyFieldException(
                    "docproFormato");
            }

            if ((docproFormato != null) &&
                    (Utilities.checkWordAndCheckWithlength(docproFormato, 80) == false)) {
                throw new ZMessManager().new NotValidFormatException(
                    "docproFormato");
            }

            if (proCodigo_Proyecto == null) {
                throw new ZMessManager().new EmptyFieldException(
                    "proCodigo_Proyecto");
            }

            if (tipdocCodigo_TipoDocumento == null) {
                throw new ZMessManager().new EmptyFieldException(
                    "tipdocCodigo_TipoDocumento");
            }

            IProyectoLogic logicProyecto1 = new ProyectoLogic();
            ITipoDocumentoLogic logicTipoDocumento2 = new TipoDocumentoLogic();
            Proyecto proyectoClass = logicProyecto1.getProyecto(proCodigo_Proyecto);
            TipoDocumento tipoDocumentoClass = logicTipoDocumento2.getTipoDocumento(tipdocCodigo_TipoDocumento);

            if (proyectoClass == null) {
                throw new ZMessManager().new ForeignException("proyecto");
            }

            if (tipoDocumentoClass == null) {
                throw new ZMessManager().new ForeignException("tipoDocumento");
            }

            entity = getDocumentosProyecto(docproCodigo);

            if (entity != null) {
                throw new ZMessManager(ZMessManager.ENTITY_WITHSAMEKEY);
            }

            entity = new DocumentosProyecto();
            //entity.setDocproArchivo(docproArchivo);
            entity.setDocproCodigo(docproCodigo);
            entity.setDocproFormato(docproFormato);
            entity.setProyecto(proyectoClass);
            entity.setTipoDocumento(tipoDocumentoClass);
            HibernateSessionFactory.beginTransaction();
            XMLHibernateDaoFactory.getInstance().getDocumentosProyectoDAO()
                                  .save(entity);
            HibernateSessionFactory.commit();
        } catch (Exception e) {
            HibernateSessionFactory.rollback();
            throw e;
        } finally {
            HibernateSessionFactory.closeSession();
        }
    }
    
    public void SaveDocuments (List<File> doc,String cod) throws Exception{
    	try {      	
        	
        	List<DocumentosProyecto> documentosProyectos= new ArrayList<DocumentosProyecto>();
        	Proyecto proyecto = null;
        	for (File f : doc) {
        		
        		FileInputStream fi= new FileInputStream(f);
        		byte[]buffer= new byte[(int)f.length()];
        		int readers=fi.read(buffer);
        		DocumentosProyecto trabajo = new DocumentosProyecto();
        		trabajo.setDocproArchivo(buffer);
        		String[] a= f.getAbsolutePath().split("\\.");
        		System.out.println(a.length);
        		trabajo.setDocproNombre(f.getName());
        		trabajo.setDocproFormato(a[a.length-1]);
        		 proyecto = BusinessDelegatorView.getProyectoporNombre(cod);
        		trabajo.setProyecto(proyecto);
        		trabajo.setTipoDocumento(BusinessDelegatorView.getTipoDocumento(proyecto.getTipoProyecto().getTipproCodigo()));
        		documentosProyectos.add(trabajo);
			}
        	List<DocumentosProyecto> proyectos = BusinessDelegatorView
			.getDocumentoProyectoPorProyecto(proyecto
					.getProCodigo());
        	List<DocumentosProyecto> removes = new ArrayList<DocumentosProyecto>();
        	for (int i = 0; i < proyectos.size(); i++) {
        		boolean a = true;
				for (DocumentosProyecto documentoProyecto : documentosProyectos) {
					if (proyectos.get(i).getDocproNombre().equals(documentoProyecto.getDocproNombre())){
						a = false;
						break;
					}
				}
				if (a == true){
					removes.add(proyectos.get(i));
				}
        	}
        	for (DocumentosProyecto documentosProyecto : proyectos) {
				for (DocumentosProyecto documentoProyecto : documentosProyectos) {
					if (documentosProyecto.getDocproNombre().equals(documentoProyecto.getDocproNombre())){
						documentosProyectos.remove(documentoProyecto);
					}
				}
			}
        	
        	HibernateSessionFactory.beginTransaction();
        	for (int i = 0; i <documentosProyectos.size(); i++) {
        		 XMLHibernateDaoFactory.getInstance().getDocumentosProyectoDAO().save(documentosProyectos.get(i));
        		 
			}
        	for (int i = 0; i < removes.size(); i++) {
        		XMLHibernateDaoFactory.getInstance().getDocumentosProyectoDAO().delete(removes.get(i));
			}
        	HibernateSessionFactory.commit();
        	
        	
        	
    	

        } catch (Exception e) {
        	HibernateSessionFactory.rollback();
            throw e;
        } finally {
        	HibernateSessionFactory.closeSession();
        }
    }

    public void deleteDocumentosProyecto(Integer docproCodigo)
        throws Exception {
        DocumentosProyecto entity = null;

        if (docproCodigo == null) {
            throw new ZMessManager().new EmptyFieldException("docproCodigo");
        }

        List<ActaSeguimientoProyectoGrado> actaSeguimientoProyectoGrados = null;
        List<AprobacionAnteproyecto> aprobacionAnteproyectos = null;
        List<ReciboProyectoGrado> reciboProyectoGrados = null;
        List<RevisionProyectoGrado> revisionProyectoGrados = null;
        entity = getDocumentosProyecto(docproCodigo);

        if (entity == null) {
            throw new ZMessManager().new EmptyFieldException(
                "DocumentosProyecto");
        }

        try {
            actaSeguimientoProyectoGrados = XMLHibernateDaoFactory.getInstance()
                                                                  .getActaSeguimientoProyectoGradoDAO()
                                                                  .findByProperty("documentosProyecto.docproCodigo",
                    docproCodigo);

            if (Utilities.validationsList(actaSeguimientoProyectoGrados) == true) {
                throw new ZMessManager().new DeletingException(
                    "actaSeguimientoProyectoGrados");
            }

            aprobacionAnteproyectos = XMLHibernateDaoFactory.getInstance()
                                                            .getAprobacionAnteproyectoDAO()
                                                            .findByProperty("documentosProyecto.docproCodigo",
                    docproCodigo);

            if (Utilities.validationsList(aprobacionAnteproyectos) == true) {
                throw new ZMessManager().new DeletingException(
                    "aprobacionAnteproyectos");
            }

            reciboProyectoGrados = XMLHibernateDaoFactory.getInstance()
                                                         .getReciboProyectoGradoDAO()
                                                         .findByProperty("documentosProyecto.docproCodigo",
                    docproCodigo);

            if (Utilities.validationsList(reciboProyectoGrados) == true) {
                throw new ZMessManager().new DeletingException(
                    "reciboProyectoGrados");
            }

            revisionProyectoGrados = XMLHibernateDaoFactory.getInstance()
                                                           .getRevisionProyectoGradoDAO()
                                                           .findByProperty("documentosProyecto.docproCodigo",
                    docproCodigo);

            if (Utilities.validationsList(revisionProyectoGrados) == true) {
                throw new ZMessManager().new DeletingException(
                    "revisionProyectoGrados");
            }

            HibernateSessionFactory.beginTransaction();
            XMLHibernateDaoFactory.getInstance().getDocumentosProyectoDAO()
                                  .delete(entity);
            HibernateSessionFactory.commit();
        } catch (Exception e) {
            HibernateSessionFactory.rollback();
            throw e;
        } finally {
            HibernateSessionFactory.closeSession();
        }
    }

    public void updateDocumentosProyecto(Long docproArchivo,
        Integer docproCodigo, String docproFormato, Integer proCodigo_Proyecto,
        Integer tipdocCodigo_TipoDocumento) throws Exception {
        DocumentosProyecto entity = null;

        try {
            if (docproArchivo == null) {
                throw new ZMessManager().new EmptyFieldException(
                    "docproArchivo");
            }

            if (docproCodigo == null) {
                throw new ZMessManager().new EmptyFieldException("docproCodigo");
            }

            if (docproFormato == null) {
                throw new ZMessManager().new EmptyFieldException(
                    "docproFormato");
            }

            if ((docproFormato != null) &&
                    (Utilities.checkWordAndCheckWithlength(docproFormato, 80) == false)) {
                throw new ZMessManager().new NotValidFormatException(
                    "docproFormato");
            }

            if (proCodigo_Proyecto == null) {
                throw new ZMessManager().new EmptyFieldException(
                    "proCodigo_Proyecto");
            }

            if (tipdocCodigo_TipoDocumento == null) {
                throw new ZMessManager().new EmptyFieldException(
                    "tipdocCodigo_TipoDocumento");
            }

            IProyectoLogic logicProyecto1 = new ProyectoLogic();

            ITipoDocumentoLogic logicTipoDocumento2 = new TipoDocumentoLogic();
            Proyecto proyectoClass = logicProyecto1.getProyecto(proCodigo_Proyecto);
            TipoDocumento tipoDocumentoClass = logicTipoDocumento2.getTipoDocumento(tipdocCodigo_TipoDocumento);

            if (proyectoClass == null) {
                throw new ZMessManager().new ForeignException("proyecto");
            }

            if (tipoDocumentoClass == null) {
                throw new ZMessManager().new ForeignException("tipoDocumento");
            }

            entity = getDocumentosProyecto(docproCodigo);

            if (entity == null) {
                throw new ZMessManager(ZMessManager.ENTITY_NOENTITYTOUPDATE);
            }

            //entity.setDocproArchivo(docproArchivo);
            entity.setDocproCodigo(docproCodigo);
            entity.setDocproFormato(docproFormato);
            entity.setProyecto(proyectoClass);
            entity.setTipoDocumento(tipoDocumentoClass);
            HibernateSessionFactory.beginTransaction();
            XMLHibernateDaoFactory.getInstance().getDocumentosProyectoDAO()
                                  .update(entity);
            HibernateSessionFactory.commit();
        } catch (Exception e) {
            HibernateSessionFactory.rollback();
            throw e;
        } finally {
            HibernateSessionFactory.closeSession();
        }
    }

    public DocumentosProyecto getDocumentosProyecto(Integer docproCodigo)
        throws Exception {
        DocumentosProyecto entity = null;

        try {
            entity = XMLHibernateDaoFactory.getInstance()
                                           .getDocumentosProyectoDAO()
                                           .findById(docproCodigo);
        } catch (Exception e) {
            throw new ZMessManager().new FindingException("DocumentosProyecto");
        } finally {
        }

        return entity;
    }

    public List<DocumentosProyecto> findPageDocumentosProyecto(
        String sortColumnName, boolean sortAscending, int startRow,
        int maxResults) throws Exception {
        List<DocumentosProyecto> entity = null;

        try {
            entity = XMLHibernateDaoFactory.getInstance()
                                           .getDocumentosProyectoDAO()
                                           .findPageDocumentosProyecto(sortColumnName,
                    sortAscending, startRow, maxResults);
        } catch (Exception e) {
            throw new ZMessManager().new FindingException("DocumentosProyecto");
        } finally {
        }

        return entity;
    }

    public Long findTotalNumberDocumentosProyecto() throws Exception {
        Long entity = null;

        try {
            entity = XMLHibernateDaoFactory.getInstance()
                                           .getDocumentosProyectoDAO()
                                           .findTotalNumberDocumentosProyecto();
        } catch (Exception e) {
            throw new ZMessManager().new FindingException(
                "DocumentosProyecto Count");
        } finally {
        }

        return entity;
    }

    /**
    *
    * @param varibles
    *            este arreglo debera tener:
    *
    * [0] = String variable = (String) varibles[i]; representa como se llama la
    * variable en el pojo
    *
    * [1] = Boolean booVariable = (Boolean) varibles[i + 1]; representa si el
    * valor necesita o no ''(comillas simples)usado para campos de tipo string
    *
    * [2] = Object value = varibles[i + 2]; representa el valor que se va a
    * buscar en la BD
    *
    * [3] = String comparator = (String) varibles[i + 3]; representa que tipo
    * de busqueda voy a hacer.., ejemplo: where nombre=william o where nombre<>william,
        * en este campo iria el tipo de comparador que quiero si es = o <>
            *
            * Se itera de 4 en 4..., entonces 4 registros del arreglo representan 1
            * busqueda en un campo, si se ponen mas pues el continuara buscando en lo
            * que se le ingresen en los otros 4
            *
            *
            * @param variablesBetween
            *
            * la diferencia son estas dos posiciones
            *
            * [0] = String variable = (String) varibles[j]; la variable ne la BD que va
            * a ser buscada en un rango
            *
            * [1] = Object value = varibles[j + 1]; valor 1 para buscar en un rango
            *
            * [2] = Object value2 = varibles[j + 2]; valor 2 para buscar en un rango
            * ejempolo: a > 1 and a < 5 --> 1 seria value y 5 seria value2
                *
                * [3] = String comparator1 = (String) varibles[j + 3]; comparador 1
                * ejemplo: a comparator1 1 and a < 5
                    *
                    * [4] = String comparator2 = (String) varibles[j + 4]; comparador 2
                    * ejemplo: a comparador1>1  and a comparador2<5  (el original: a > 1 and a <
                            * 5) *
                            * @param variablesBetweenDates(en
                            *            este caso solo para mysql)
                            *  [0] = String variable = (String) varibles[k]; el nombre de la variable que hace referencia a
                            *            una fecha
                            *
                            * [1] = Object object1 = varibles[k + 2]; fecha 1 a comparar(deben ser
                            * dates)
                            *
                            * [2] = Object object2 = varibles[k + 3]; fecha 2 a comparar(deben ser
                            * dates)
                            *
                            * esto hace un between entre las dos fechas.
                            *
                            * @return lista con los objetos que se necesiten
                            * @throws Exception
                            */
    public List<DocumentosProyecto> findByCriteria(Object[] variables,
        Object[] variablesBetween, Object[] variablesBetweenDates)
        throws Exception {
        List<DocumentosProyecto> list = new ArrayList<DocumentosProyecto>();
        String where = new String();
        String tempWhere = new String();

        if (variables != null) {
            for (int i = 0; i < variables.length; i++) {
                if ((variables[i] != null) && (variables[i + 1] != null) &&
                        (variables[i + 2] != null) &&
                        (variables[i + 3] != null)) {
                    String variable = (String) variables[i];
                    Boolean booVariable = (Boolean) variables[i + 1];
                    Object value = variables[i + 2];
                    String comparator = (String) variables[i + 3];

                    if (booVariable.booleanValue()) {
                        tempWhere = (tempWhere.length() == 0)
                            ? ("(model." + variable + " " + comparator + " \'" +
                            value + "\' )")
                            : (tempWhere + " AND (model." + variable + " " +
                            comparator + " \'" + value + "\' )");
                    } else {
                        tempWhere = (tempWhere.length() == 0)
                            ? ("(model." + variable + " " + comparator + " " +
                            value + " )")
                            : (tempWhere + " AND (model." + variable + " " +
                            comparator + " " + value + " )");
                    }
                }

                i = i + 3;
            }
        }

        if (variablesBetween != null) {
            for (int j = 0; j < variablesBetween.length; j++) {
                if ((variablesBetween[j] != null) &&
                        (variablesBetween[j + 1] != null) &&
                        (variablesBetween[j + 2] != null) &&
                        (variablesBetween[j + 3] != null) &&
                        (variablesBetween[j + 4] != null)) {
                    String variable = (String) variablesBetween[j];
                    Object value = variablesBetween[j + 1];
                    Object value2 = variablesBetween[j + 2];
                    String comparator1 = (String) variablesBetween[j + 3];
                    String comparator2 = (String) variablesBetween[j + 4];
                    tempWhere = (tempWhere.length() == 0)
                        ? ("(" + value + " " + comparator1 + " " + variable +
                        " and " + variable + " " + comparator2 + " " + value2 +
                        " )")
                        : (tempWhere + " AND (" + value + " " + comparator1 +
                        " " + variable + " and " + variable + " " +
                        comparator2 + " " + value2 + " )");
                }

                j = j + 4;
            }
        }

        if (variablesBetweenDates != null) {
            for (int k = 0; k < variablesBetweenDates.length; k++) {
                if ((variablesBetweenDates[k] != null) &&
                        (variablesBetweenDates[k + 1] != null) &&
                        (variablesBetweenDates[k + 2] != null)) {
                    String variable = (String) variablesBetweenDates[k];
                    Object object1 = variablesBetweenDates[k + 1];
                    Object object2 = variablesBetweenDates[k + 2];
                    String value = null;
                    String value2 = null;

                    try {
                        Date date1 = (Date) object1;
                        Date date2 = (Date) object2;
                        value = Utilities.formatDateWithoutTimeInAStringForBetweenWhere(date1);
                        value2 = Utilities.formatDateWithoutTimeInAStringForBetweenWhere(date2);
                    } catch (Exception e) {
                        list = null;
                        throw e;
                    }

                    tempWhere = (tempWhere.length() == 0)
                        ? ("(model." + variable + " between \'" + value +
                        "\' and \'" + value2 + "\')")
                        : (tempWhere + " AND (model." + variable +
                        " between \'" + value + "\' and \'" + value2 + "\')");
                }

                k = k + 2;
            }
        }

        if (tempWhere.length() == 0) {
            where = null;
        } else {
            where = "(" + tempWhere + ")";
        }

        try {
            list = XMLHibernateDaoFactory.getInstance()
                                         .getDocumentosProyectoDAO()
                                         .findByCriteria(where);
        } catch (Exception e) {
            throw new Exception(e.getMessage());
        } finally {
        }

        return list;
    }

	public DocumentosProyecto getDocumentosProyectopro(String proCodigo,
			String tipproCodigoTipoProyecto) throws Exception {
		DocumentosProyecto entity = null;

        try {
            entity = XMLHibernateDaoFactory.getInstance()
                                           .getDocumentosProyectoDAO()
                                           .getDocumentosProyectopro(proCodigo,tipproCodigoTipoProyecto);
        } catch (Exception e) {
            throw new ZMessManager().new FindingException(
                "DocumentosProyecto Count");
        } finally {
        }

        return entity;
	}

	public List<DocumentosProyecto> getDocumentoProyectoPorProyecto(Integer proCodigo)
			throws Exception {
		List<DocumentosProyecto> entity = null;

        try {
        	entity = XMLHibernateDaoFactory.getInstance()
            .getDocumentosProyectoDAO()
            .findByProperty("proyecto.proCodigo", proCodigo);
            
        } catch (Exception e) {
            throw e;
        } finally {
        }

        return entity;
	}
}
